mod error_propagating;
mod storage_error_method;

use std::collections::*;
use rand::Rng;
use std::{thread, time};
use std::borrow::Borrow;
use std::time::{Duration, Instant};
use hashbrown::HashMap as hashbrownHashMap;
use std::fs;
use std::fs::File;
use std::io::ErrorKind;
use crate::error_propagating::{exist_file_propagating, not_exist_file_propagating};
use crate::storage_error_method::method_;

fn main() {
    // // error  1
    // panic!("crash and burn");

    // // error 2
    // // 尝试通过索引访问 vector 中元素. 如果尝试读取一个索引不存在的元素，Rust 会停止执行并拒绝继续。
    // let v = vec![1, 2, 3];
    // v[99];

    // exception and retry
    // 打开一个并不存在的文件失败，此时创建这个文件，而不是终止进程。
    createFile1();

    createFile2();

    createFile3(String::from("hello3.txt"));
    // createFile4(String::from("hello3.txt"));

    // 在这里, 如果报错,则不会 panic中断, 会返回错误
    let errMsg = not_exist_file_propagating();
    println!("create file error:{}.", errMsg);
    let errMsg = exist_file_propagating();
    println!("create file data:{}.", errMsg);

    let msg = method_();
    println!("method_ data:{}.", msg.as_ref().unwrap());
    assert_eq!(msg.unwrap(), "rfghjkfvbn");

}

fn createFile1(){
    // File::open 调用可能会成功并返回一个可以进行读写的文件句柄。这个函数也可能会失败：例如，文件可能并不存在，或者可能没有访问文件的权限。
    let fileRs = File::open("hello.txt");
    // 当 File::open 成功的情况下，变量 f 的值将会是一个包含文件句柄的 Ok 实例。
    // 在失败的情况下，f 的值会是一个包含更多关于出现了何种错误信息的 Err 实例。
    let file = match fileRs {
        Ok(file) => {
            println!("open file.");
            file
        },
        Err(error) => match error.kind() {
            // 尝试打开的文件并不存在，则创建文件
            ErrorKind::NotFound => match File::create("hello.txt") {
                Ok(fc) => {
                    println!("create file:{}.", "hello.txt");
                    fc
                },
                Err(e) => panic!("Problem creating the file: {:?}", e),
            },
            other_error => {
                panic!("Problem opening the file: {:?}", other_error)
            }
        },
    };

    fs::remove_file("hello.txt").expect("TODO: panic message");
}

fn createFile2(){
    // File::open 调用可能会成功并返回一个可以进行读写的文件句柄。这个函数也可能会失败：例如，文件可能并不存在，或者可能没有访问文件的权限。
    let fileRs = File::open("hello1.txt")
        .unwrap_or_else(|error| {
            if error.kind() == ErrorKind::NotFound {
                File::create("hello1.txt").unwrap_or_else(|error| {
                    panic!("Problem creating the file: {:?}", error);
                })
            } else {
                panic!("Problem opening the file: {:?}", error);
            }
        });

    fs::remove_file("hello1.txt").expect("TODO: panic message");
}

fn createFile3(filePath: String){
    // File::open 调用可能会成功并返回一个可以进行读写的文件句柄。这个函数也可能会失败：例如，文件可能并不存在，或者可能没有访问文件的权限。
    let fileRs = File::open(&filePath)
        .unwrap_or_else(|error| {
            if error.kind() == ErrorKind::NotFound {
                File::create(&filePath).unwrap()
            } else {
                panic!("Problem opening the file: {:?}", error);
            }
        });

    fs::remove_file(filePath).expect("TODO: panic message");
}

fn createFile4(filePath: String){
    let fileRs = File::open(String::from("aa")).expect("文件打开错误");
}